# Starting PIC microcontroller programming – Part 2/2 (First project)

09-01-2016 Alex Microcontrollers, Tutorials 0

So we’ve completed the first part of this tutorial, and are now ready to start doing interesting things. It’s time to build a simple circuit and put some life in it with a program. We’ll start with something very basic, and program our microcontroller to blink a LED blink.

After getting the components we need, we’ll wire the circuit on a breadboard and then write the program.

# Bill of Material

We will need a few components for this tutorial, but you probably have most of them already:

- PIC programmer: we talked about it in the first part of this tutorial, it’s the tool we’ll use to transfer our program in the PIC.
- PIC16F88: you can use any PIC microcontroller you’d like, and this exact reference is just the one I’ll be using in this tutorial. This one is about $2.60 on Newark. I would advise to stay in the PIC16F or PIC18F families, as they are both widely used (hence big online support) and relatively easy to work with. If you’re starting you definitely want to stay away from the dsPIC and PIC32 families, which are way too complicated for beginners.

- Breadboard: we’ll use it to connect our components together. You can use any type of breadboard, I personally use a few medium-size breadboards (about $10 for 3 on Amazon) and some little ones (about $6.50 for 6 on Amazon).
- Capacitors:
  - One 0.1uF decoupling capacitor on the Vdd pin (a ceramic capacitor is better).
- One 330Ω resistor to protect the LED. The value can be a bit different as long as it doesn’t allow too much current for the LED.
- One LED of your choice. Just make sure you add a resistor in series to protect it.
- A power supply of your choice. You can, in theory, use the PICkit 3 to power your circuit. However I recommend providing power from an external source, the main reason being that if you power your circuit from the PICkit 3, the power will come from your computer’s USB port. Although it is not a problem for this project as we’ll only draw a few milliamps, it’s good to get used to using an external source. I will present a simple way to build a power supply down below. Here are the additional parts you will need if you want to build the same:
  - One 9V DC wall adapter (about $7 on Adafruit)
  - A breadboard barrel jack (about $1 on Adafruit) to plug your adapter in your breadboard.
  - One LM7805 ($0.75 on Adafruit). It’s a DC to DC voltage regulator that will convert the 9V from the wall adapter, into a stable 5V that will power our microcontroller.
  - A 0.33uF and a 0.1uF ceramic capacitor.

# Hardware

Before wiring anything, make sure your power source is not plugged in. You should never touch a circuit when it’s powered. Although we work with small currents and voltages, it’s a good habit to take because you’ll be used to it whenever you manipulate higher power circuits.

## Power supply

If you decide to power your circuit from the PICkit 3 or another power supply, you can skip to the next part of the circuit.

I won’t give too much details on how to build this simple power supply, as we will talk about it much more in depth in this tutorial. Here is the circuit we’ll build to create our stable 5V voltage. We simply need to connect the LM7805 and two capacitors as shown below.

5V DC power supply using a LM7805

And here is a picture of it built on a breadboard:

Power supply on the breadboard

## Rest of the circuit

We first need to look at the datasheet for the PIC16F88, that you can find here. On the pin diagram, we note where the pins Vss and Vdd are. We connect them respectively to the ground (middle pin of the LM7805) and our 5V voltage (pin 3 of the LM7805, on the right side on the previous picture).

Add a 0.1uF ceramic capacitor between the Vdd pin and Vss. It’s not mandatory, but it’s a highly recommended practice to add such a capacitor on every Vdd pin of an integrated circuit. It’s called a decoupling capacitor, and is used to cancel (at least attenuate) any variation in the power supply voltage.

Next, connect a LED on the pin RA0 of the microcontroller, and add a 330Ω resistor in series.

To sum it up, here is a schematic of the circuit we built so far. Please note that the locations of the pins on the schematics are different than they are on the actual microcontroller.

Basic PIC16F88 circuit

Now let’s add our programmer to the circuit. The PICkit 3 uses a 6-pin ICSP connector, with the following pinout. Pin 1 is indicated on the PICkit 3 by a little triangle.

Standard 6-pin ICSP connector

We’re going to connect the signals of the PICkit 3 to the PIC16F88 like so:

- /MCLR – Pin 4 (RA5/MCLR/VPP)
- VDD – 5V from the LM7805 (pin 3)
- GND – 0V from the LM7805 (middle pin)
- PGD – Pin 13 (RB7/AN6/PGD/ T1OSI)
- PGC – Pin 12 (RB6/AN5/PGC/ T1OSO/T1CKI)
- PGM – Pin 9 (RB3/PGM/CCP1)

So if we put everything together, with the power supply, the ICSP connector for the PICkit 3 and the main circuitry, we now have the following circuit.

LED blinking circuit

And it looks like this on a breadboard:

Basic circuit for blinking a LED

# Software

## Configuration of the PIC

Now let’s write a basic piece of software to make the LED blink. First, we need to configure the PIC. It’s a bit of an annoying step, but it’s mandatory for every project. We need to tell the microcontroller the basic parameter it will use, such as the clock source and frequency, or whether we want to use the reset pin or have it behave like a normal I/O pin, for example.

In MPLAB X, click on Windows =>PIC Memory Views => Configuration Bits. It will open a window showing the bits we can configure in the CONFIG1 and CONFIG2 registers. Enter the following information:

Select your configuration for the CONFIG registers

Then, click on Generate Source Code to Output, and copy/paste the generated code at the top of your main file.

We just need a few more lines in the main() function. There are a few parameters that we can’t configure using the configuration bits. We’ll write them in the main function.

We configure the clock frequency and source by writing in the bits IRCF and SCS of the OSCCON register, like shown below. In case you wonder how I found the names of the registers and the values they can take, they can always be found in the datasheet of the microcontroller, they’re not black magic!

Configuration of the clock and I/O ports
C
void main(void) { OSCCONbits.IRCF = 0b111; // Set internal oscillator frequency to 8MHz OSCCONbits.SCS = 0b10; // Internal RC is used for system clock

1 2 3 | void main(void) { OSCCONbits.IRCF = 0b111; // Set internal oscillator frequency to 8MHz OSCCONbits.SCS = 0b10; // Internal RC is used for system clock

Then we tell the microcontroller we want to disable the analog pins, so they can be used as digital pins:

C
ANSEL = 0x00; // Set all I/O to digital I/O

1 | ANSEL = 0x00; // Set all I/O to digital I/O

Finally, we set the pin RA0 to be an output, by writing 0 to its TRIS register. When you select the direction of a pin or port in their TRIS register, remember that 0 stands for Output (0 and O are similar), and 1 stands for Input (1 and I are similar).

C
TRISAbits.TRISA0 = 0; // Set RA0 as output

1 | TRISAbits.TRISA0 = 0; // Set RA0 as output

## Make this LED blink!

The basic idea we’ll use to make the LED blink, is to repeatedly toggle its state and wait for a moment. In order to wait, we’ll use the function __delay_ms();, which is offered by our compiler and will wait for the amount of milliseconds you put in the parenthesis. Before using it though, we have to tell the compiler at what frequency the PIC will be running. We do this by defining _XTAL_FREQ just after we include xc.h.

C
#include <xc.h> #define _XTAL_FREQ 8000000 // System clock frequency

1 2 | #include <xc.h> #define _XTAL_FREQ 8000000 // System clock frequency

Now in the main function, we create a while(1) loop that will run indefinitely. This is the basic structure of an embedded application, it is not supposed to stop running because there is no operating system to take control in case it stops. If the program stops, it will not start over until someone resets or reprograms the microcontroller.

Anyway, in this loop, we simply toggle the state of the pin RA0, and then we wait for 1000ms (1 second).

C
while(1) { PORTAbits.RA0 = ~PORTAbits.RA0; // Toggle LED pin __delay_ms(1000); }

1 2 3 4 5 | while(1) { PORTAbits.RA0 = ~PORTAbits.RA0; // Toggle LED pin __delay_ms(1000); }

To sum it up, the code for the full program is the following:

Program to blink a LED
C
// CONFIG1 #pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTRC oscillator; port I/O function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital I/O, MCLR internally tied to VDD) #pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled) #pragma config LVP = ON // Low-Voltage Programming Enable bit (RB3/PGM pin has PGM function, Low-Voltage Programming enabled) #pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off) #pragma config CCPMX = RB0 // CCP1 Pin Selection bit (CCP1 function on RB0) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) // CONFIG2 #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled) #pragma config IESO = OFF // Internal External Switchover bit (Internal External Switchover mode disabled) #include <xc.h> #define _XTAL_FREQ 8000000 // System clock frequency void main(void) { OSCCONbits.IRCF = 0b111; // Set internal oscillator frequency to 8MHz OSCCONbits.SCS = 0b10; // Internal RC is used for system clock ANSEL = 0x00; // Set all I/O to digital I/O TRISAbits.TRISA0 = 0; // Set RA0 as output while(1) { PORTAbits.RA0 = ~PORTAbits.RA0; // Toggle LED pin __delay_ms(1000); } return; }

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | // CONFIG1 #pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTRC oscillator; port I/O function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital I/O, MCLR internally tied to VDD) #pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled) #pragma config LVP = ON // Low-Voltage Programming Enable bit (RB3/PGM pin has PGM function, Low-Voltage Programming enabled) #pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off) #pragma config CCPMX = RB0 // CCP1 Pin Selection bit (CCP1 function on RB0) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) // CONFIG2 #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled) #pragma config IESO = OFF // Internal External Switchover bit (Internal External Switchover mode disabled) #include <xc.h> #define _XTAL_FREQ 8000000 // System clock frequency void main(void) { OSCCONbits.IRCF = 0b111; // Set internal oscillator frequency to 8MHz OSCCONbits.SCS = 0b10; // Internal RC is used for system clock ANSEL = 0x00; // Set all I/O to digital I/O TRISAbits.TRISA0 = 0; // Set RA0 as output while(1) { PORTAbits.RA0 = ~PORTAbits.RA0; // Toggle LED pin __delay_ms(1000); } return; }

It may seem big, but if you think about it, once the configuration is done, we only wrote a couple of lines to actually make the LED blink.

# Let’s try it!

Okay, we have the circuit built and the code to make the LED blink. Now it’s time to power your circuit, and if nothing burns in smoke, you can program the microcontroller with the program we just wrote. To do so, click on Make and Program Device Main Project (the icon with an arrow pointing to the microcontroller).

Program the PIC

If everything goes well, your PicKit 3 should output something similar to the following text in the bottom window.

Successful programmation
C
***************************************************** Connecting to MPLAB PICkit 3... Currently loaded firmware on PICkit 3 Firmware Suite Version.....01.43.35 Firmware type..............Midrange Target voltage detected Target device PIC16F88 found. Device ID Revision = 8 The following memory area(s) will be programmed: program memory: start address = 0x0, end address = 0x7ff configuration memory Device Erased... Programming... Programming/Verify complete

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | ***************************************************** Connecting to MPLAB PICkit 3... Currently loaded firmware on PICkit 3 Firmware Suite Version.....01.43.35 Firmware type..............Midrange Target voltage detected Target device PIC16F88 found. Device ID Revision = 8 The following memory area(s) will be programmed: program memory: start address = 0x0, end address = 0x7ff configuration memory Device Erased... Programming... Programming/Verify complete

Congratulations! The LED is blinking, you have created your first circuit and program!

If you have any question or problem, please leave a comment below; I will try my best to help you!

Circuit with the LED on
LED on
LED off

# More content?

For more microcontrollers and PIC tutorials, be sure to check out microcontrollers page! Subscribe below to receive our future articles:

Please leave this field empty

Email *

Subscription successful!

### Share this:

- Email
- Twitter
- Facebook
- Google

### Like this:

Like Loading...

### Related

Starting PIC microcontroller programming - Part 1/2 (Setting up the tools)08-29-2016 In "Microcontrollers"

How to use UART with a PIC microcontroller 08-06-2017 In "Microcontrollers"

Interfacing a 7 segment display with a PIC16F microcontroller 09-21-2016 In "Electronics"

- microcontroller
- mplab x
- PIC16F88
- PICkit 3

#### Be the first to comment

You must log in to post a comment.

Copyright © The Embedded Lab 2016 - 2018 | The Embedded Lab is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn fees by linking to Amazon.com and affiliated sites.

%d bloggers like this:

Send to Email Address Your Name Your Email Address Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.